home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- ;
- ; Screen erase program - by Bob Murphy 9/16/84
- ;
- ; This program will erase the display after the specified number of minutes.
- ; Any Video I/O or Keyboard I/O will cause a restore of the display.
- ;
- ;
- ; FORMAT:
- ;
- ; SCRNSAVE [NN]
- ;
- ; WHERE NN IS A 1 OR 2 DIGIT NUMBER OF MINUTES BETWEEN 1 AND 29.
- ; THE DEFAULT VALUE IS 5 MINUTES.
- ;
- ;
- ;
-
- ; DEFINE THE CODE SEGMENT, AND SET THINGS UP FOR A .COM PROGRAM
-
- CSEG SEGMENT PARA PUBLIC 'CODE'
- ASSUME CS:CSEG, DS:CSEG
- ORG 100H
-
- START: JMP INIT000 ;JUMP AROUND THE DATA AREA
- ;
- ; EQUATES
- ;
- ADDR_6845 EQU 63H ; CRT CONTROL PORT BASE ADDRESS
- CRT_MODE_SET EQU 65H ; CURRENT STATE OF CRT MODE REGISTER
- ;
- ; MISC DATA FIELDS
- ;
- INITFLAG DB 0 ;USED TO DETERMINE IF WE SHOULD STAY RES
- SWFLAG DB 0 ;VIDEO NOT SWITHCED OFF (1 IF WE DID)
- COUNT DW 0 ;TIMER COUNT
- DELAY DW 0 ;COUNT FOR TIME-OUT
- PGM_ID DB 'SCRNSAVE' ;THIS MUST BE AFTER CRTJMP!
- PGM_IDL EQU $-PGM_ID ;COMPARE LENGTH
- PAGE
- ;
- ; INTERRUPT VECTOR CONTROL BLOCKS. ALL 3 MUST BE IDENTICAL
- ;
- ; TIMER TICK INTERRUPT TABLE
- ;
- TIMER LABEL DWORD ;ADDRESS OF REAL TIMER INT
- TIMEOFF DW 0
- TIMESEG DW 0
- TIMEADDR DW TIMETICK ;OFFSET OF NEW TIMER INTERRUPT
- TIMEINT DB 1CH ;TIMER INTERRUPT NUMBER
- DB 0 ;SPARE
- INTBLK EQU $-TIMER ;LENGTH OF AN INTERRUPT CONTROL BLOCK
-
- ;
- ; KEY STRIKE INTERRUPT TABLE
- ;
- KEY LABEL DWORD ;ADDRESS OF REAL KEYBOARD INT
- DW 0
- DW 0
- DW KEY_IN ;OFFSET OF NEW KB INTERRUPT
- DB 09H ;KB INTERRUPT ADDRESS
- DB 0 ;SPARE
-
- ;
- ; CRT OUTPUT INTERRUPT TABLE
- ;
- CRT LABEL DWORD ;ADDRESS OF REAL VIDEO INT (INT 10H)
- DW 0
- DW 0
- DW CRTOUT ;OFFSET OF NEW TIMER INTERRUPT
- DB 10H ;VIDEO INTERRUPT NUMBER
- DB 0 ;SPARE
-
- PAGE
- ;
- ;PROCESS THE 1CH INTERRUPT WHICH OCCURS 18.2 TIMES PER SECOND
- ;
- TIMETICK:
- STI ;RESTORE INTERRUPTS
- PUSH AX ;SAVE SOME REGISTERS
- PUSH DS
- MOV AX,CS
- MOV DS,AX ;SET THE DS REGISTER SAME AS CS
- MOV AX,COUNT
- INC AX
- MOV COUNT,AX ;INCREMENT THE VALUE
- CMP AX,DELAY ;UNTIL WE GET TO SELECTED DELAY
- ;THIS VALUE IS 444H PER MINUTE
- JL TIME800 ;LESS THAN DELAY TIME - SKIP TURN OFF
- ;
- ; SHUT OFF VIDEO OPERATION
- ;
- PUSH DX ;SAVE THESE REGISTERS, TOO
- PUSH ES
- MOV AX,0040H ;BIOS DATA AREA BASE
- MOV ES,AX
- MOV DX,ES:ADDR_6845 ;GET BASE ADDRESS OF THE VIDEO CONTROLLER
- ADD DX,4 ;POINT TO CONTROLLER'S MODE REGISTER
- MOV AL,ES:CRT_MODE_SET ;GET CURRENT MODE SETTINGS
- AND AL,11110111B ;CLEAR THE VIDEO ENABLE BIT TO
- OUT DX,AL ;TURN OFF THE VIDEO.
- POP ES
- POP DX
- MOV SWFLAG,1 ;FLAG THAT WE HAVE SWITCHED OFF
- ;
- ; GO TO THE STANDARD TIMER INTERRUPT
- ;
- TIME800:
- POP DS ;STANDARD EXIT. RESTORE USED REGISTERS
- POP AX ;AND PROCESS WHATEVER WAS AT INT 1CH
- PUSHF ;BEFORE THIS PROGRAM CAME INTO ACTION.
- CALL CS:TIMER ;PUSH DUMMY FLAGS, AND FAKE AN INT 1CH
- IRET
- PAGE
- ;
- ; THE USER HAS PRESSED A KEY...
- ;
- KEY_IN:
- STI ;RESTORE INTERRUPTS
- CALL CHKSCRN ;IF SCREEN OFF - TURN IT BACK ON
- PUSHF ;DUMMY PUSH TO FAKE AN INT INSTRUCTION
- CALL CS:KEY ;GO TO REAL KEYBOARD ROUTINE
- IRET ;AND RETURN TO WHAT WAS RUNNING BEFORE
- ;
- ;THE SYSTEM WANTS TO OUTPUT TO THE SCREEN...
- ;
- CRTOUT:
- STI ;RESTORE INTERRUPTS
- CALL CHKSCRN ;IF CRT IS OFF-TURN IT BACK ON
- PUSHF ;FAKE AN INT 10H
- CALL CS:CRT ;PROCESS THE VIDEO REQUEST
- IRET ;GO BACK TO CALLING PROGRAM
- ;
- ; A KEY HAS BEEN PRESSED OR CRT WRITE ATTEMPTED - TURN SCREEN BACK ON
- ;
- CHKSCRN PROC NEAR
- CMP CS:SWFLAG,0 ;HAVE WE SWITCHED THE VIDEO OFF?
- JE CHKS400 ;NO-SKIP
- PUSH AX ;SAVE REGISTERS
- PUSH DS
- PUSH DX
- PUSH ES
- MOV AX,CS
- MOV DS,AX ;SET THE DS REGISTER SAME AS CS
- MOV AX,0040H ;FIRST, POINT TO THE ROM DATA AREA
- MOV ES,AX
- MOV DX,ES:ADDR_6845 ;GET BASE ADDRESS OF VIDEO CONTROLLER
- ADD DX,4 ;AND POINT TO CONTROLLER MODE REGISTER
- MOV AL,ES:CRT_MODE_SET ;GET THE OLD MODE SETTINGS AND
- OUT DX,AL ;RESTORE THEM.
- MOV SWFLAG,0 ;NOT SWITCHED OFF ANYMORE
- POP ES
- POP DX
- POP DS ;RESTORE REGISTERS
- POP AX
- CHKS400:
- MOV CS:COUNT,0 ;RESET (AGAIN) COUNT TO 0
- RET
- CHKSCRN ENDP
- ;
- END_PR: ;USED TO DETERMINE LENGTH OF PROGRAM
- PAGE
- ERR1MSG DB 'PARM MUST BE A NUMBER BETWEEN 1 AND 29',7,13,10,'$'
- GOODMSG DB 13,10,'SCREEN SAVER INITIALIZED',13,10,'$'
- RESTMSG DB 13,10,'SCREEN SAVER TIME RESET',13,10,'$'
- ;
- ; INITIALIZATION CODE - DOES NOT STAY RESIDENT
- ;
- INIT000: MOV AX,5 ;DEFAULT TIME VALUE
- MOV SI,80H ;SEE IF ANY INPUT DATA
- MOV CL,[SI] ;GET CHARACTER COUNT
- SUB CH,CH
- OR CL,CL ;ANYTHING INPUT?
- JZ INIT100 ;NO-USE DEFAULT 5 MINUTE DELAY
- MOV DL,10 ;MULTIPLY VALUE
- SUB AX,AX ;VALUE ACCUMULATION REGISTER
- SUB BH,BH ;HI SIDE OF PICKUP REG = 0 FOR ADD
- INIT020: INC SI ;POINT TO CHARACTER
- MOV BL,[SI]
- CMP BL,' ' ;BLANK?
- JE INIT040 ;YES-DISCARD IT
- CMP BL,'0' ;CHK FOR DIGIT
- JL INIT900 ;INVALID - THEN ERR1
- CMP BL,'9' ;SAME THING
- JG INIT900 ;FALL THRU ON A VALID DIGIT
- SUB BL,'0' ;SET RANGE 0-9
- MUL DL
- ADD AX,BX ;SUM DIGITS
- CMP AX,29 ;EXCEED MAX TIME OF 29 MINUTES?
- JG INIT900 ;YES-ERROR
- INIT040: LOOP INIT020 ;DO NEXT DIGIT
- OR AX,AX ;ZERO TIME?
- JZ INIT900 ;YES-INVALID TIME
- PAGE
- ;
- ; AX CONTAINS A VALID TIME PERIOD (0 < AX < 30). SEE IF PGM LOADED BEFORE
- ;
- ; CRT VECTOR SELECTED, BECAUSE ITS THE LEAST LIKELY TO BE MODIFIED BY A
- ; SUBSEQUENT PROGRAM. (WHO WOULD WANT TO TRAP THE VIDEO ROUTINE?)
- ;
- INIT100: PUSH AX
- MOV AH,35H ;GET VECTOR COMMAND
- MOV AL,10H ;FOR CRT
- INT 21H ;POINT TO CRT VECTOR W/ES:BX
- ; ;IF PGM LOADED BEFORE, ES IS THE BASE
- MOV CX,PGM_IDL ;COMPARE LENGTH
- MOV SI,OFFSET PGM_ID ;POINT TO THIS PROGRAM ID
- MOV DI,SI
- REP CMPSB ;SEE IF PROGRAM ID MATCH OCCURS
- JNE INIT200 ;IF DIFFERENT, WE WANT TO STAY RESIDENT
- MOV INITFLAG,1 ;SET DONT STAY RESIDENT
- PUSH ES ;ES HAS BASE OF RESIDENT VERSION
- POP DS ;USE DELAY FIELD IN RESIDENT COPY
-
- INIT200: POP AX ;RESTORE TIME COUNT
- MOV BX,444H ;TICKS PER MINUTE
- MUL BX ;CONVERT MINUTES TO TICKS
- MOV DELAY,AX ;SAVE DELAY TIME PERIOD
- PUSH CS
- POP DS ;SEE THAT WERE USING OUR OWN PROGRAM
-
- CMP INITFLAG,0 ;ARE WE GOING TO STAY RESIDENT?
- JNZ INIT940 ;NO-THEN VECTORS ALREADY SET
- PAGE
- ;
- ; INITIALIZE TIMER, KEYBOARD, AND CRT VECTORS
- ;
- SUB SI,SI ;START INITIALIZATION WITH TIMER INT
- MOV CX,3 ; 3 INTS TO INITIALIZE
- SUB AX,AX
- MOV ES,AX ;ADDRESS LOW CORE
- INIT400: CALL SETVEC ;INITIALIZE 1 INTERRUPT VECTOR
- ADD SI,INTBLK ;INDEX TO NEXT BLOCK
- LOOP INIT400 ;DO ALL 3
- MOV DX,OFFSET GOODMSG
- MOV AH,9
- INT 21H ;SEND MESSAGE
- MOV DX,OFFSET END_PR ;POINT TO END OF RESIDENT CODE
- INT 27H ;TERM & STAY RESIDENT
- ;
- ;
- INIT900: MOV DX,OFFSET ERR1MSG ;ERROR IN PARAMETER
- JMP INIT980
- INIT940: MOV DX,OFFSET RESTMSG ;PGM RESIDENT ALREADY-TIME RESET
- JMP INIT980
- INIT980: MOV AH,9
- INT 21H ;SEND MESSAGE
- INT 20H ;ABORT
- ;
- ; SET UP AN INTERRUPT VECTOR FROM VECTOR ASSIGNMENT TABLE
- ;
- SETVEC PROC NEAR
- MOV AL,TIMEINT [SI] ;GET INTERRUPT ADDRESS TO MODIFY
- MOV AH,35H ;GET GET VECTOR DOS CALL
- INT 21H ;RETURN VECTOR IN ES:BX
- MOV TIMEOFF [SI],BX ;SAVE ORIGINAL VECTOR OFFSET
- MOV BX,ES ;GET SEGMENT
- MOV TIMESEG [SI],BX ;SAVE ORIGINAL VECTOR SEGMENT
- MOV DX,TIMEADDR [SI] ;GET REPLACEMENT INTERRUPT VECTOR OFFSET
- MOV AH,25H ;SET UP NEW VECTOR FOR TIMER ETC
- INT 21H ;HAVE DOS DO THIS FOR US
- RET ;ALL DONE WITH THIS VECTOR
- SETVEC ENDP
-
- CSEG ENDS
- END START